package com.mycompany.app.hr.common;

import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.springframework.context.i18n.LocaleContextHolder;

/**
 * 异常基类. 带有错误代码与错误信息. 用户在生成异常时既可以直接赋予错误代码与错误信息. 也可以只赋予错误代码与错误信息参数.
 */
public class BaseAppException extends Exception {

    private static final long serialVersionUID = -4500155572436658380L;

    /**
     * 错误代码,默认为未知错误
     */
    protected String errorCode = "UNKNOW_ERROR";

    /**
     * 错误信息中的参数
     */
    protected String[] errorArgs = null;

    /**
     * 兼容纯错误信息，不含error code,errorArgs的情况
     */
    protected String errorMessage = null;

    /**
     * 错误信息的i18n ResourceBundle. 默认Properties文件名
     */
    private static ResourceBundle rb = ResourceBundle.getBundle(
            Constants.MESSAGE_BUNDLE_KEY, LocaleContextHolder.getLocale());

    public BaseAppException() {

        super();
    }

    public BaseAppException(String message) {

        super(message);
    }

    public BaseAppException(Throwable cause) {

        super(cause);
    }

    public BaseAppException(String message, Throwable cause) {

        super(message, cause);
    }

    /**
     * 获得出错信息. 读取i18N properties文件中Error Code对应的message,并组合参数获得i18n的出错信息.
     */
    public String getMessage() {

        // 如果errorMessage不为空,直接返回出错信息.
        if (errorMessage != null) {
            return errorMessage;
        }
        // 否则用errorCode查询Properties文件获得出错信息
        String message;
        try {
            message = rb.getString(errorCode);
        } catch (MissingResourceException mse) {
            message = "ErrorCode is: " + errorCode
                    + ", but can't get the message of the Error Code";
        }

        // 将出错信息中的参数代入到出错信息中
        if (errorArgs != null)
            message = MessageFormat.format(message, (Object[]) errorArgs);

        return message + ", Error Code is: " + errorCode;

    }

    public String getErrorCode() {

        return errorCode;
    }

}